package cn.iocoder.yudao.module.engine.service.core.engine.impl;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.server.websocket.security.WebSocketUser;
import cn.iocoder.yudao.module.engine.dal.redis.engine.EngineLockRedisDAO;
import cn.iocoder.yudao.module.engine.enums.SensorTypeEnum;
import cn.iocoder.yudao.module.engine.model.context.ControlEngineContext;
import cn.iocoder.yudao.module.engine.model.context.EngineSessionContext;
import cn.iocoder.yudao.module.engine.model.context.EngineSynStatusCacheContext;
import cn.iocoder.yudao.module.engine.model.engine.EngineInputData;
import cn.iocoder.yudao.module.engine.model.engine.EngineOutputData;
import cn.iocoder.yudao.module.engine.model.websoket.EngineInputDataVO;
import cn.iocoder.yudao.module.engine.model.websoket.EngineOutputDataVO;
import cn.iocoder.yudao.module.engine.service.core.engine.IControlEngineService;
import cn.iocoder.yudao.module.engine.service.core.pipeline.FilterManager;
import cn.iocoder.yudao.module.engine.service.log.IEngineLogService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import java.util.stream.Collectors;

@Service
@Slf4j
public class ControlEngineServiceImpl implements IControlEngineService {
    @Resource
    private IEngineLogService logService;
    @Resource
    private EngineLockRedisDAO engineLockRedisDAO;

    @Override
    public EngineOutputDataVO handleInputData(EngineSessionContext engineSessionContext,
                                              EngineSynStatusCacheContext cacheContext,
                                              WebSocketUser user, EngineInputDataVO inputData) {
        return engineLockRedisDAO.lockWsSession(engineSessionContext.getWsSessionId(), () -> {
            log.info("引擎输入, inputData = {}", inputData);
            return doHandleInputData(engineSessionContext, cacheContext, user, inputData);
        });
    }

    @NotNull
    private EngineOutputDataVO doHandleInputData(EngineSessionContext engineSessionContext,
                                                 EngineSynStatusCacheContext cacheContext,
                                                 WebSocketUser user,
                                                 EngineInputDataVO inputData) {
        // ctx
        final ControlEngineContext engineContext = new ControlEngineContext(
                engineSessionContext, cacheContext, user, BeanUtils.toBean(inputData, EngineInputData.class)
        );
        logInput(engineSessionContext, inputData);

        // 执行pipeline.read
        FilterManager.getInstance().getPipeline().fireRead(engineContext);
        final EngineOutputData outputData = engineContext.getOutputData();
        log.info("执行pipeline.read, outputData = {}", outputData);

        // 执行pipeline.write
        //FilterManager.getInstance().getPipeline().write(engineContext);
        //log.info("执行pipeline.write, outputData = {}", outputData);

        final EngineOutputDataVO outputDataVO = BeanUtils.toBean(outputData, EngineOutputDataVO.class);
        return outputDataVO;
    }

    private void logInput(EngineSessionContext engineSessionContext, EngineInputDataVO inputData) {
        if (inputData.getAudioText() != null && StrUtil.isNotEmpty(inputData.getAudioText().getText())) {
            logService.log(engineSessionContext, "【输入音频】" + inputData.getAudioText().getText());
        }

        if (inputData.getSensors() != null) {
            final String sensorInput = String.join(", ",
                    inputData.getSensors().stream().map(v -> SensorTypeEnum.fromValue(v.getSensorType()).getName()
                            + StrUtil.format(" -> (闭合次数: {}, X轴: {}, Y轴: {}, Z轴: {})",
                            v.getUpCount(), v.getXAxis(), v.getYAxis(), v.getZAxis())).collect(Collectors.toList()));
            logService.log(engineSessionContext, "【输入传感器】" + sensorInput);
        }
    }

}
